﻿Imports System.Text.RegularExpressions
''' <summary>
''' Manages the abstraction and management of basic type patterns from data.
''' </summary>
Public Class BasicPatternAbstraction
    Private Enum CharType
        UAlpha = 0
        LAlpha = 1
        Alpha = 2
        Numeric = 3
        LAlpha_Numeric = 4
        UAlpha_Numeric = 5
        Alphanumeric = 6
        NonAlphaNumeric = 7
        NonNumeric = 8
        NonAlpha = 9
        All = 10
        Exact = 11
    End Enum
    Private Structure Term
        Dim Type As CharType
        Dim Length As Long
        Dim Character As Char
    End Structure
    Dim gP() As Term
    ''' <summary>
    ''' Returns a string representing the match in the form of a regular expression.
    ''' </summary>
    ReadOnly Property Pattern() As String
        'COMPLETE
        Get
            Return Substitute_Enums()
        End Get
    End Property
    ''' <summary>
    ''' Updates the pattern profile.
    ''' </summary>
    ''' <param name="Data">Data with which to update the pattern.</param>
    Sub Update_Pattern(ByVal Data As String)
        Dim i As Long
        If Not IsArray(gP) Then
            ReDim gP(Len(Data) - 1)
            For i = 0 To Len(Data) - 1
                gP(i).Character = Mid(Data, i + 1, 1)
                gP(i).Type = CharType.Exact
                gP(i).Length = 1
            Next i
        End If
        'Now we have a set of characters and types.
        For i = 0 To UBound(gP)
            If Not gP(i).Character = Mid(Data, i + 1, 1) Then
                gP(i).Type = Evolve(Mid(Data, i + 1, 1), gP(i).Type, gP(i).Character)
            End If
        Next
        'Update Last Charset
        For i = 0 To UBound(gP)
            gP(i).Character = Mid(Data, i + 1, 1)
        Next
    End Sub
    ''' <summary>
    ''' Determines whether a string matches a pattern or not.
    ''' </summary>
    ''' <param name="Data">Data to check for pattern</param>
    ''' <param name="strict">If true string must match exactly. If false the match can exist in other content.</param>
    ''' <returns>Returns true if the data matches the pattern. False if it does not.</returns>
    Function Match(ByVal Data As String, Optional ByVal strict As Boolean = False) As Boolean
        If Regex.Match(Data, Pattern).Success Then Return True
    End Function
    ''' <summary>
    ''' Searches for patterns and replaces found matches.
    ''' </summary>
    ''' <param name="Data">Data to search for matches in.</param>
    ''' <param name="Replace">String to substitute in for found matches.</param>
    ''' <returns>Returns true if the data matches the pattern. False if it does not.</returns>
    Function Substitute(ByVal Data As String, ByVal Replace As String) As String

    End Function
    Private Function Substitute_Enums() As String
        Dim i As Long, Expression As String = ""
        For i = 0 To UBound(gP)
            Select Case gP(i).Type
                Case CharType.Alpha
                    Expression = Expression & "[a-zA-Z]"
                Case CharType.Numeric
                    Expression = Expression & "[0-9]"
                Case CharType.All
                    Expression = Expression & "(.)"
                Case CharType.LAlpha
                    Expression = Expression & "[a-z]"
                Case CharType.UAlpha
                    Expression = Expression & "[A-Z]"
                Case CharType.LAlpha_Numeric
                    Expression = Expression & "[a-z0-9]"
                Case CharType.UAlpha_Numeric
                    Expression = Expression & "[A-Z0-9]"
                Case CharType.NonNumeric
                    Expression = Expression & "[^0-9]"
                Case CharType.NonAlpha
                    Expression = Expression & "[^a-zA-Z]"
                Case CharType.NonAlphaNumeric
                    Expression = Expression & "[^0-9a-zA-Z]"
                Case CharType.Alphanumeric
                    Expression = Expression & "[0-9a-zA-Z]"
                Case CharType.Exact
                    Expression = Expression & gP(i).Character
            End Select
            Expression = Expression & "{1}"
        Next
        Return Expression
    End Function
    Private Function Evolve(ByVal Data As Char, ByVal Original_Type As CharType, ByVal Orig_Data As String) As CharType
        'This function accepts a character, and the original type of the character and resolves the new character type
        Dim T1 As CharType, T2 As CharType
        T2 = Me.Get_Type(Data)
        T1 = Original_Type
        If T1 = CharType.Exact Then T1 = Me.Get_Type(Orig_Data)
        If T1 = T2 Then Return T1
        If (T1 = CharType.Alpha And T2 = CharType.Numeric) Or (T1 = CharType.Numeric And T2 = CharType.Alpha) Then Return CharType.Alphanumeric
        'If T1 = CharType.Exact Then Return T2
        If (T1 = CharType.LAlpha And T2 = CharType.UAlpha) Or (T1 = CharType.UAlpha And T2 = CharType.LAlpha) Then Return CharType.Alpha
        If (T1 = CharType.LAlpha_Numeric And T2 = CharType.UAlpha) Or (T1 = CharType.UAlpha And T2 = CharType.LAlpha_Numeric) Then Return CharType.Alphanumeric
        If (T1 = CharType.UAlpha_Numeric And T2 = CharType.LAlpha) Or (T1 = CharType.LAlpha And T2 = CharType.UAlpha_Numeric) Then Return CharType.Alphanumeric
        If (T1 = CharType.Alphanumeric And T2 = CharType.Numeric) Or (T2 = CharType.Alphanumeric And T1 = CharType.Numeric) Then Return (CharType.Alphanumeric)


        Return CharType.All
    End Function
    Private Function Get_Type(ByVal Data As Char) As CharType
        'COMPLETE
        If IsNumeric(Data) Then Return CharType.Numeric
        If Me.IsLString(Data) Then Return CharType.LAlpha
        If Me.IsUString(Data) Then Return CharType.UAlpha
        If Not IsNumeric(Data) And Not IsAlpha(Data) Then Return CharType.NonAlphaNumeric
        Return CharType.All
    End Function
    Private Function IsAlpha(ByVal Data As String) As Boolean
        'COMPLETE
        If IsLString(LCase(Data)) Then Return True
    End Function
    Private Function IsUString(ByVal Data As String) As Boolean
        'COMPLETE
        Return Regex.Match(Data, "^[A-Z]+$").Success
    End Function
    Private Function IsLString(ByVal Data As String) As Boolean
        'COMPLETE
        Return Regex.Match(Data, "^[a-z]+$").Success
    End Function
End Class
